package aop;

import java.util.Arrays;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 使用注解定义切面
 * @author Dylan
 *
 */
@Component
@Aspect
public class TheLog {
	private static final Logger log = Logger.getLogger(TheLog.class);
	
	@Pointcut("execution(* service..*.*(..))")
	public void pointcut(){
		
	}
	
	//前置增强
	@Before("pointcut()")
	public void myBefore(JoinPoint jp){
		log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。方法的入参为："+Arrays.toString(jp.getArgs()));
	}
	
	//后置增强
	@AfterReturning(pointcut="pointcut()",returning="result")
	public void myAfterReturning(JoinPoint jp,Object result){
		log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。返回值："+result);
	}
	
	//异常
	@AfterThrowing(pointcut="pointcut()",throwing="e")
	public void myError(JoinPoint jp,Exception e){
		log.error(jp.getTarget()+"中"+jp.getSignature().getName()+"方法发生异常："+e);
	}
	
	//最终
	@After("pointcut()")
	public void myAfter(JoinPoint jp){
		log.error(jp.getTarget()+"中"+jp.getSignature().getName()+"方法执行结束");
	}
	
	//环绕
	//@Around("pointcut()")
	public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable{
		log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。方法的入参为："+Arrays.toString(jp.getArgs()));
		
		try {
			Object result = jp.proceed();
			log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。返回值："+result);
			return result;
		} catch (Exception e) {
			log.error(jp.getTarget()+"中"+jp.getSignature().getName()+"方法发生异常："+e);
			throw e;
		} finally {
			log.error(jp.getTarget()+"中"+jp.getSignature().getName()+"方法执行结束");
		}
	}

}
